<?php

include_once("Dijkstra.php");

class GrafoBD {
	private $resultSelectNodos;
	private $resultSelectAristas;
	private $graph = array();
	private $rutaConNombres = array();
	private $tipoRuta;
	private $transportesIdeales;
	private $patronZonaOrigen;
	private $patronZonaDestino;
	private $uriMaps;
	private $transporteElegido;
	private $nodosLatitudes = array();
	private $nodosLongitudes = array();
	private $latitudes = array();
	private $longitudes = array();
	
	public function __construct($tipoRuta, $transportesIdeales) {
		# Set inicial de atributos
		$tipoRuta === "Rápida" ? $this->tipoRuta = "tiempo" : $this->tipoRuta = "distancia";
		$this->transportesIdeales = $transportesIdeales;
		$this->uriMaps = 0;
		
		# Conectamos con MySQL
		$conexion = mysql_connect("localhost","root") or die ("Fallo en el establecimiento de la conexión con la base de datos");
		mysql_select_db("datosgrafo") or die("Error en la selección de la base de datos");
		mysql_query("SET NAMES 'utf8'");
		$this->resultSelectNodos = mysql_query ("select * from nodo" );
		$this->resultSelectAristas = mysql_query ("select * from arista" );
		mysql_close($conexion);
	}
	
	public function __destruct() {
		# Liberamos recursos
		mysql_free_result($this->resultSelectNodos);
		mysql_free_result($this->resultSelectAristas);
	}
	
	private function crearGrafo($patronTransporteF) {
		$this->graph = array();
		while($row = mysql_fetch_array($this->resultSelectNodos)) {
			# Aprovechamos y guardamos las coordenadas
			$this->nodosLatitudes[$row["idNodo"]] = $row["latitud"];
			$this->nodosLongitudes[$row["idNodo"]] = $row["longitud"];
			if (preg_match($patronTransporteF, $row["descripcion"])){
				while($rowArista = mysql_fetch_array($this->resultSelectAristas)){
					if (preg_match($patronTransporteF, $rowArista["tipoTransporte"])){
						if($rowArista["puntoOrigen"] === $row["idNodo"]){
							$arrayNodo = array();
							$arrayNodo[] = $rowArista["puntoOrigen"];
							$arrayNodo[] = $rowArista["puntoDestino"];
							$arrayNodo[] = $rowArista[$this->tipoRuta];
							$this->graph[] = $arrayNodo;
						}
					}
				}
				# Reseteamos el cursor a la posición inicial
				mysql_data_seek($this->resultSelectAristas, 0);
			}
		}
		# Reseteamos el cursor a la posición inicial
		mysql_data_seek($this->resultSelectNodos, 0);
	}
	
	/*
	private function quitarBicicletasDelGrafo() {
		# Borrar bicis del grafo si hace falta
		foreach ($this->graph as $arista) {
			if ($arista[0][0] === '3' || $arista[1][0] === '3') {
				if (($key = array_search($arista, $this->graph)) !== false) {
					array_splice($this->graph, $key, 1);
				}
			}
		}
	}
	*/
	
	private function anyadirWaypoints($path) {
		# Obtenemos los waypoints
		$arrayLatitudes = array();
		$arrayLongitudes = array();
		foreach ($path as $nodo) {
			$arrayLatitudes[] = $this->nodosLatitudes[$nodo];
			$arrayLongitudes[] = $this->nodosLongitudes[$nodo];
		}
		# Añadimos los waypoints
		if (count($arrayLatitudes) > 2) {
			$this->uriMaps .= "&waypoints=";
			foreach ($arrayLatitudes as $key=>$latitud) {
				if (($key !== 0) && ($key !== count($arrayLatitudes)-1))
					$this->uriMaps .= $arrayLatitudes[$key].",".$arrayLongitudes[$key]."|";
			}
			// Borrar la última barra
			$this->uriMaps = rtrim($this->uriMaps, '|');
		}
	}
	
	private function crearURIMaps($path, $nodoOrigen, $nodoDestino) {
		# Creamos una URI prelminiar con el origen y destino, faltan los waypoints
		$this->uriMaps = "https://www.google.com/maps/embed/v1/directions?key=AIzaSyDEx5DlGJN02YhYbGMeBxyJ70Mhb55CIuM";
		$this->uriMaps .= "&origin=".$this->nodosLatitudes[$nodoOrigen].",".$this->nodosLongitudes[$nodoOrigen];
		$this->uriMaps .= "&destination=".$this->nodosLatitudes[$nodoDestino].",".$this->nodosLongitudes[$nodoDestino];
		if ($this->transporteElegido === "Metro")
			$this->uriMaps .= "&mode=transit";
		else if ($this->transporteElegido === "Autobús" || $this->transporteElegido === "Tranvía")
			$this->uriMaps .= "&mode=driving";
		else if ($this->transporteElegido === "Bicicleta")
			$this->uriMaps .= "&mode=walking";
		else if ($this->transporteElegido === "Transbordo") {
			$this->uriMaps .= "&mode=walking";
			$this->anyadirWaypoints($path);
		}
	}
	
	public function calcularRuta($source, $target) {
		$nodoOrigen = "NULL";
		$nodoDestino = "NULL";
		$coste = 0;
		$j = 0;
		
		# Adivinar número de nodos a partir de los nombres teniendo en cuenta las preferencias de transporte
		while ($nodoOrigen === "NULL" || $nodoDestino === "NULL") {
			if ($j < count($this->transportesIdeales)-1) {
				echo 'Intentando usar sólamente '.$this->transportesIdeales[$j].'...<br>';
				$this->crearGrafo("/.*".strval($this->transportesIdeales[$j]).".*/");
				$this->patronZonaOrigen = "/.*".$this->transportesIdeales[$j].".*$source$/";
				$this->patronZonaDestino = "/.*".$this->transportesIdeales[$j].".*$target$/";
				$this->transporteElegido = $this->transportesIdeales[$j];
			} else if ($j == count($this->transportesIdeales)-1) { # Si ya no hay mas medios disponibles hacer transbordos
				echo 'Intentando usar cualquier tipo de transporte y transbordo...<br>';
				$this->crearGrafo("/.*/");
				$this->patronZonaOrigen = "/.*$source$/";
				$this->patronZonaDestino = "/.*$target$/";
				$this->transporteElegido = "Transbordo";
			} else { # Si no hay ruta posible...
				echo '<br><h4>¡NO HAY RUTAS POSIBLES!</h4><br>';
				return 0;
			}
			
			$nodoOrigen = "NULL";
			$nodoDestino = "NULL";
			while($row = mysql_fetch_array($this->resultSelectNodos)) {
				if (preg_match($this->patronZonaOrigen, $row["descripcion"]))
					$nodoOrigen = $row["idNodo"];
				if (preg_match($this->patronZonaDestino, $row["descripcion"]))
					$nodoDestino = $row["idNodo"];
			}
			# Reseteamos el cursor a la posición inicial
			mysql_data_seek($this->resultSelectNodos, 0);
			$j++;
		}
		# Reseteamos el cursor a la posición inicial
		mysql_data_seek($this->resultSelectNodos, 0);
		echo '<br>';
		
		# Calculamos la ruta ideal
		$path = Dijkstra::calcularRutaCorta($this->graph, $nodoOrigen, $nodoDestino, $coste);
		
		# Creamos la URI para Google Maps
		$this->crearURIMaps($path, $nodoOrigen, $nodoDestino);
		
		# Rellenar un array con Nombres a partir de los idNodos de $path
		while($row = mysql_fetch_array($this->resultSelectNodos)) {
			foreach ($path as $key=>$nodo) {
				if ($nodo === $row["idNodo"]) {
					$this->rutaConNombres[$key] = $row["descripcion"];
				}
			}
		}
		# Reseteamos el cursor a la posición inicial
		mysql_data_seek($this->resultSelectNodos, 0);
		
		# Ordenamos el array
		ksort($this->rutaConNombres);
		
		# Imprimir ruta antes de limpieza
		//echo implode('<br>', $this->rutaConNombres).'<br>';
		
		# Borramos los nodos que sobren al principio
		$tamanyoArray = count($this->rutaConNombres);
		for ($i = 1; $i < $tamanyoArray; $i++) {
			# Si coincide el nombre de la zona...
			if (strstr($this->rutaConNombres[$i-1], ' ') === strstr($this->rutaConNombres[$i], ' ')) {
				if ($i == 1) # Y es el primero...
					array_splice($this->rutaConNombres, $i-1, 1); # Borrar
				# Quitar uno al tamaño del array a procesar	ya que hemos borrado un elemento
				$i--;
				$tamanyoArray--;
			}
		}
		
		# Borramos los nodos que sobren al final
		$tamanyoArray = count($this->rutaConNombres);
		for ($i = $tamanyoArray-1; $i > 0; $i--) {
			# Si coincide el nombre de la zona...
			if (strstr($this->rutaConNombres[$i-1], ' ') === strstr($this->rutaConNombres[$i], ' ')) {
				if ($i == $tamanyoArray-1) # Y es el último...
					array_splice($this->rutaConNombres, $i, 1); # Borrar
				# Quitar uno al tamaño del array a procesar	ya que hemos borrado un elemento
				$tamanyoArray--;
			}
		}
		
		# Imprimimos
		echo '<br><img src="img/route.png" border=0>';
		echo '<h4>';
		echo 'La ruta es:';
		echo '</h4>';
		echo implode('<br>', $this->rutaConNombres).'<br>';
		echo '<h4>';
		echo '<br>Con un coste de: '.$coste; $this->tipoRuta === "tiempo" ? print (" minutos") : print (" kilómetros");
		echo '</h4><br>';
		
		# Devolvemos la URI para que resultados.php genere el mapa
		return $this->uriMaps;
	}
}
